package scheduler

import (
	"crypto/rand"
	"encoding/hex"
	"time"
)

// generateID generates a unique ID
func generateID() string {
	b := make([]byte, 8)
	rand.Read(b)
	return hex.EncodeToString(b)
}

// calculateTimeWindow calculates a time window for predictions
func calculateTimeWindow(current time.Time, duration time.Duration) (time.Time, time.Time) {
	start := current.Add(-duration)
	end := current.Add(duration)
	return start, end
}

// calculateMovingAverage calculates moving average of values
func calculateMovingAverage(values []float64, window int) float64 {
	if len(values) == 0 {
		return 0
	}
	if len(values) < window {
		window = len(values)
	}

	sum := 0.0
	for i := len(values) - window; i < len(values); i++ {
		sum += values[i]
	}
	return sum / float64(window)
}

// calculateExponentialMovingAverage calculates EMA
func calculateExponentialMovingAverage(values []float64, alpha float64) float64 {
	if len(values) == 0 {
		return 0
	}

	ema := values[0]
	for i := 1; i < len(values); i++ {
		ema = alpha*values[i] + (1-alpha)*ema
	}
	return ema
}

// calculatePredictionConfidence calculates prediction confidence
func calculatePredictionConfidence(actual, predicted float64) float64 {
	if actual == 0 {
		return 0
	}
	error := abs(actual-predicted) / actual
	return 1 - error
}

// abs returns absolute value of float64
func abs(x float64) float64 {
	if x < 0 {
		return -x
	}
	return x
}
